import json
import requests
import sys

sys.path.append("..")

import pandas as pd
from urllib.parse import urljoin
from tools.wrappers import deco_retry

header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
base_url = 'https://api.llama.fi/'

@deco_retry(retry=5, retry_sleep=15)
def get_all_protocol_info(**kwargs):
    # DefiLlama网站上的所有DEFI协议相关信息(......)，按照锁仓规模排序
    url = urljoin(base_url, "protocols")
    a = requests.get(url, headers=header, timeout=30)
    res = json.loads(a.text)
    df = pd.DataFrame(res)
    return df


@deco_retry(retry=5, retry_sleep=15)
def get_current_tvl_by_protocol(protocol_name='LIDO', **kwargs):
    # DefiLlama网站上的该协议上的当前总锁仓量
    if not protocol_name == 'all':
        url = urljoin(base_url, f"tvl/{protocol_name}")
        a = requests.get(url, headers=header, timeout=30)
        res = json.loads(a.text)
    else:
        df = get_all_protocol_info()
        res = df[['name', 'symbol', 'slug', 'tvl']]
    return res


def get_detailed_tvl_by_protocol(protocol_name='LIDO', tvl_type='chainTvls', **kwargs):
    # DefiLlama网站上的该DEFI协议的基本信息，还包括全历史锁仓量信息，不同链上的全历史锁仓量信息， 以及不同tokens被锁了多少在该协议上
    url = urljoin(base_url, f"protocol/{protocol_name}")
    a = requests.get(url, headers=header, timeout=30)
    res = json.loads(a.text)
    if tvl_type == 'chainTvls':
        all_tvl_df_list = []
        for chain in res[tvl_type].keys():
            tvl_list = res[tvl_type][chain]['tvl']
            df = pd.DataFrame(tvl_list)
            df.rename(columns={'totalLiquidityUSD': chain}, inplace=True)
            df.set_index('date', inplace=True)
            all_tvl_df_list.append(df)
        all_df = pd.concat(all_tvl_df_list, axis=1)
    elif 'token' in tvl_type:
        tvl_list = []
        if 'tokens' not in res.keys():
            return None
        for data in res[tvl_type]:
            x = data['tokens']
            x.update({'date': data['date']})
            tvl_list.append(x)
        all_df = pd.DataFrame(tvl_list)
        if all_df.empty:
            return None
        else:
            all_df.set_index('date', inplace=True)

    elif tvl_type == 'tvl':
        all_df = pd.DataFrame(res[tvl_type])
        all_df.rename(columns={'totalLiquidityUSD': 'tvl'}, inplace=True)
        all_df.set_index('date', inplace=True)

    all_df.index.name = 'timestamp'
    all_df.reset_index(inplace=True)
    all_df['date'] = pd.to_datetime(all_df['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    all_df['date'] = all_df['date'].dt.strftime('%Y-%m-%d')
    all_df['datetime'] = pd.to_datetime(all_df['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    all_df['datetime'] = all_df['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S')
    all_df = all_df.iloc[:-1, ]
    all_df.set_index('date', inplace=True)
    return all_df


def get_total_tvl_by_tokens(currency_type='crypto', **kwargs):
    # DefiLlama网站上的该链上的历史总锁仓量
    if currency_type == 'usd':
        tvl_type = 'tokensInUsd'
    else:
        tvl_type = 'tokens'
    df = get_all_protocol_info()
    all_protocol_slug = df['slug']
    df_list = []
    for slug in all_protocol_slug:
        df = get_detailed_tvl_by_protocol(protocol_name=slug, tvl_type=tvl_type, **kwargs)
        if df is None:
            continue
        df.set_index('timestamp', inplace=True)
        df_list.append(df.iloc[:, :-2])
    temp_df = df_list[0]
    for i in df_list[1:]:
        temp_df = temp_df + i
    return temp_df


@deco_retry(retry=5, retry_sleep=15)
def get_total_tvl(**kwargs):
    # DefiLlama网站上的全部链上加总的历史总锁仓量
    url = urljoin(base_url, "charts")
    a = requests.get(url, headers=header, timeout=30)
    res = json.loads(a.text)
    all_df = pd.DataFrame(res)
    all_df.set_index('date', inplace=True)
    all_df.index.name = 'timestamp'
    all_df.reset_index(inplace=True)
    all_df['date'] = pd.to_datetime(all_df['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    all_df['date'] = all_df['date'].dt.strftime('%Y-%m-%d')
    all_df['datetime'] = pd.to_datetime(all_df['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    all_df['datetime'] = all_df['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S')
    return all_df


@deco_retry(retry=5, retry_sleep=15)
def get_current_total_tvl_all_chain(**kwargs):
    # DefiLlama网站上的各链上的当前锁仓量
    url = urljoin(base_url, "chains")
    a = requests.get(url, headers=header, timeout=30)
    res = json.loads(a.text)
    all_df = pd.DataFrame(res)
    return all_df


@deco_retry(retry=5, retry_sleep=15)
def get_total_tvl_by_chain(chain='Ethereum', **kwargs):
    # DefiLlama网站上的该链上的历史总锁仓量
    url = urljoin(base_url, f"charts/{chain}")
    a = requests.get(url, headers=header, timeout=30)
    res = json.loads(a.text)
    all_df = pd.DataFrame(res)
    all_df.set_index('date', inplace=True)
    all_df.index.name = 'timestamp'
    all_df.reset_index(inplace=True)
    all_df['date'] = pd.to_datetime(all_df['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    all_df['date'] = all_df['date'].dt.strftime('%Y-%m-%d')
    all_df['datetime'] = pd.to_datetime(all_df['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    all_df['datetime'] = all_df['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S')
    return all_df


if __name__ == '__main__':
    a = get_detailed_tvl_by_protocol(protocol_name='aave-v2', tvl_type='tokensInUsd')
